package cn.ehanghai.iot.back.controller;

import cn.ehanghai.iot.back.domain.UserInfo;
import cn.ehanghai.iot.back.service.UserInfoService;
import cn.ehanghai.iot.common.controller.BaseController;
import cn.ehanghai.iot.common.security.constants.ReturnCode;
import cn.ehanghai.iot.config.DefineUtil;
import cn.ehanghai.iot.config.ProjectUrlConfig;
import cn.ehanghai.iot.config.WechatAccountConfig;
import cn.ehanghai.iot.utils.HttpUitl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.RandomUtils;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import net.sf.json.JSONObject;
import org.apache.shiro.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;


/**
 * @author xumf
 * @date 2019/6/27 19:47
 */
@Controller
@RequestMapping("/wechat")
@Slf4j
public class WechatController extends BaseController {

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private ProjectUrlConfig projectUrlConfig;

    @Autowired
    private WechatAccountConfig wechatAccountConfig;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private RedisTemplate<String,String> template;

    /**
     * 微信授权
     * @return
     */
    @GetMapping("/authorize")
    public String authorize(@RequestParam(value = "returnUrl")String returnUrl){
        log.info("returnUrl"+returnUrl);
        //1. 配置
//        String returnUrl=projectUrlConfig.getWechatreturnUrl();
        //2. 回调调用方法
        String url = projectUrlConfig.getWechatMpAuthorize() + "/wechat/userInfo";
        String redirectUrl = wxMpService.oauth2buildAuthorizationUrl(url, WxConsts.OAUTH2_SCOPE_USER_INFO, URLEncoder.encode(returnUrl));
        return "redirect:" + redirectUrl;
    }

    /**
     * 回调
     * @param code
     * @param returnUrl
     * @return
     * @throws Exception
     */
    @GetMapping("/userInfo")
    public String userInfo(@RequestParam("code") String code,
                           @RequestParam("state") String returnUrl, HttpServletRequest request) throws Exception {
        log.info("【微信网页授权】code={}", code);
        log.info("【微信网页授权】state={}", returnUrl);
        int index=returnUrl.indexOf("=");
        String fromOpenId=null;
        if(index>0){
            fromOpenId=returnUrl.substring(index+1);
        }
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken;
        try {
            wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
        } catch (WxErrorException e) {
            log.info("【微信网页授权】{}", e);
            throw new Exception(e.getError().getErrorMsg());
        }
        String openId = wxMpOAuth2AccessToken.getOpenId();
        log.info("【微信网页授权】openId={}", openId);
        WxMpUser wxMpUser=wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken,"zh_CN");
        UserInfo  userInfo =userInfoService.getUserInfoByOpenId(wxMpUser.getOpenId());
        if(userInfo==null) {
            //TODO
            userInfo = new UserInfo();
            userInfo.setOpenId(openId);
        }
        userInfo.setNickName(wxMpUser.getNickname());
        userInfo.setHead(wxMpUser.getHeadImgUrl());
        userInfo.setCountry(wxMpUser.getCountry());
        userInfo.setCity(wxMpUser.getCity());
        userInfo.setSex(wxMpUser.getSex());
        boolean result= userInfoService.userInvite(userInfo,fromOpenId);
        if(result) {
            HttpSession session = request.getSession();
            session.setAttribute("user_info", userInfo);
        }
        String newUrl=projectUrlConfig.getReturnUrl()+"?openid="+openId;
        return "redirect:" + newUrl;
    }

    /**
     * 获取签名信息
     * @param map
     * @return
     */
    @RequestMapping(value = "getSign",method = RequestMethod.GET)
    @ResponseBody
    public ReturnCode getSign(@RequestParam String url){

        String appId=wechatAccountConfig.getMpAppId();
        String secret=wechatAccountConfig.getMpAppSecret();
        String tokenUrl="https://api.weixin.qq.com/cgi-bin/token";
        String param="grant_type=client_credential&appid="+appId+"&secret="+secret+"";

        String result= HttpUitl.sendGet(tokenUrl,param);
        JSONObject json = JSONObject.fromObject(result);
        String accessToken= (String) json.get("access_token");

        String ticketUrl="https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        String ticketParam="access_token="+accessToken+"&type=jsapi";

        String result1=HttpUitl.sendGet(ticketUrl,ticketParam);
        JSONObject json1 = JSONObject.fromObject(result1);
        String jsapiTicket= (String) json1.get("ticket");

        long timestamp = System.currentTimeMillis() / 1000L;
        String nonceStr = RandomUtils.getRandomStr();
        String signature = SHA1.genWithAmple(new String[]{"jsapi_ticket=" + jsapiTicket, "noncestr=" + nonceStr, "timestamp=" + timestamp, "url=" + url});
        Map<String,Object> resultMap=new HashMap<>();
        resultMap.put("noncestr",nonceStr);
        resultMap.put("timestamp",timestamp);
        resultMap.put("appid",appId);
        resultMap.put("signature",signature);

        return success(resultMap);
    }
}
